﻿using Azure.Core;
using IM.Easy.Api.AccountManage;
using IM.Easy.AuthorizationServices.Constants;
using IM.Easy.AuthorizationServices.Dtos;
using IM.Easy.AuthorizationServices.IServices;
using IM.Easy.Core.AppContext;
using IM.Easy.Core.Attributes;
using IM.Easy.Core.Cache;
using IM.Easy.Core.Exceptions;
using IM.Easy.Core.Extensions;
using IM.Easy.Core.Utils;
using IM.Easy.CoreServices.IServices;
using IM.Easy.Entity.Authorization;
using IM.Easy.Entity.Log;
using IM.Easy.Infrastructure.Constants;
using IM.Easy.LogServices.IServices;
using IM.Easy.SystemServices.IServices;
using IM.Easy.SystemServices.Services;
using Lazy.Captcha.Core;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace IM.Easy.Api.Controllers.Authorization
{
    public class AuthorizeController : ControllerBase
    {
        private readonly IIdentityService _identityService;
        private readonly ICaptcha _captcha;
        private readonly IParamsService _paramsService;
        private readonly IRefreshTokenService _refreshTokenService;
        public AuthorizeController(IIdentityService identityService
            , IParamsService paramsServiceeds
            , ICaptcha captcha
            , IRefreshTokenService refreshTokenService)
        {
            _identityService = identityService;
            _captcha = captcha;
            _paramsService = paramsServiceeds;
            _refreshTokenService = refreshTokenService;
        }

        [HttpPost]
        [Api(Name = "获取AccessToken", AllowAnonymous = true, Required = true)]
        public TokenResponse? GetAccessToken([FromBody] LoginInput input)
        {
            TokenResponse? token = null;
            LoginUser user;
            var enableCaptcha = string.Equals(_paramsService.GetValue(ParamsConstant.VCode, true)?.Trim(), "on");
            //判断验证码
            if (enableCaptcha)
            {
                if (!_captcha.Validate(input.ConnectionId, input.Captcha)) ExceptionUtils.ThrowBusinessException("验证码错误或已过期");
            }
            //用户验证
            var result = _identityService.GetLoginUser(input);
            if (result.IsSuccess)
            {
                token = new TokenResponse();
                user = result.Data;
                var accessToken = _identityService.IssureAccessToken(user);
                var refreshToken = _refreshTokenService.Generate();
                refreshToken.UserId = user.Id;
                token.AccessToken = accessToken;
                token.RefreshToken = refreshToken.Token;
                token.ExpiresIn = 1800;
                _refreshTokenService.Create(refreshToken);
                Response.Cookies.Append("refreshToken", refreshToken.Token, new CookieOptions
                {
                    Secure = false,
                    SameSite = SameSiteMode.Lax,
                    HttpOnly = true,
                    MaxAge = TimeSpan.FromDays(3),
                });
            }
            else
            {
                ExceptionUtils.ThrowBusinessException(result.Msg);
            }
            return token;
        }

        /// <summary>
        /// 通过刷新token重新获取有效token
        /// </summary>
        /// <returns></returns>
        [HttpPut]
        [Api(Name = "刷新accessToken", AllowAnonymous = true, Required = true)]
        public TokenResponse? GetRefreshToken()
        {
            var token = new TokenResponse();
            if (!HttpContext.Request.Cookies.TryGetValue("refreshToken", out string? refreshToken))
            {
                ExceptionUtils.ThrowUnauthorized();
            }
            bool isValid = _refreshTokenService.ValidateToken(refreshToken);
            if (!isValid) ExceptionUtils.ThrowUnauthorized();
            var userId = _refreshTokenService.GetUserId(refreshToken);
            var newRefreshToken = _refreshTokenService.Generate();
            _refreshTokenService.Revoke(refreshToken, newRefreshToken.Token);
            newRefreshToken.UserId = userId;
            var accessToken = _identityService.IssureAccessToken(userId);
            token.AccessToken = accessToken;
            token.RefreshToken = newRefreshToken.Token;
            token.ExpiresIn = 1800;
            _refreshTokenService.Create(newRefreshToken);
            Response.Cookies.Append("refreshToken", newRefreshToken.Token, new CookieOptions
            {
                Secure = false,
                SameSite = SameSiteMode.Lax,
                HttpOnly = true,
                MaxAge = TimeSpan.FromDays(3),
            });
            return token;
        }

        /// <summary>
        /// 生成图片验证码
        /// </summary>
        /// <returns></returns>
        [HttpGet("captchaImage")]
        [Api(Name = "获取验证码", AllowAnonymous = true, Required = true)]
        public CaptchaDto GetCaptchaImage()
        {
            var vcode = _paramsService.GetValue(ParamsConstant.VCode, true);
            var connectionId = ImApp.Current.GetClientId();
            var info = _captcha.Generate(connectionId, 60);
            var captcha = new CaptchaDto()
            {
                CaptchaEnabled = string.Equals("on", vcode?.Trim()),
                ConnectionId = connectionId,
                Img = info.Base64
            };
            return captcha;
        }


    }
}
